#ifndef TIEC_TREE_H
#define TIEC_TREE_H

#include "foundation.h"
#include "token.h"

#define DECL_MODIFIER(name, value) static constexpr int64_t name = value;
#define DECL_VISIT_TREE(class_name) \
virtual Result visit##class_name (class_name* tree, Param param) { \
}
#define DECL_ACCEPT_VISITOR(class_name) \
template<typename Param, typename Result> \
Result accept(TreeVisitor<Param, Result> visitor, Param param) { \
  visitor.visit##class_name(this, param);\
}

namespace NS_TIEC {
  /// 语法树类型
  enum TreeKind {
    kExpression = 0,
    kStatement = 1,

    kIdentifier = 10,
    kAnnotation = 11,
    kBlock = 12,
    kVariable = 13,
    kMethod = 14,
    kEvent = 15,
    kCode = 16,
    kClass = 17,
    kTopLevel = 18,
    kIf = 19,
    kSwitch = 20,
    kCase = 21,
    kForLoop = 22,
    kForEachLoop = 23,
    kWhileLoop = 24,

    kLiteral = 30,
    kLiteralString = 31,
    kLiteralChar = 32,
    kLiteralBool = 33,
    kLiteralInt = 34,
    kLiteralLong = 35,
    kLiteralFloat = 36,
    kLiteralDouble = 37,

    kArrayType = 50,
    kTemplateType = 51,
    kFieldAccess = 52,
    kMethodInvoke = 53,
    kNewClass = 54,
    kNewArray = 55,
    kArrayAccess = 56,
    kBreak = 57,
    kContinue = 58,
    kReturn = 59,
    kSubscribeEvent = 60,
    kTypeCast = 61,
    kAssign = 62,
    kExchange = 63,
    kInstanceOf = 64,
    kMultiExpr = 65,
    kAwait = 66,
    kParens = 67,
    kUnary = 68,
    kBinary = 69,
    kCodeText = 70,
    kCodeRef = 71,
  };

  /// 方法语法树类型
  enum MethodKind {
    // 普通方法
    kCommon = 0,
    // 属性读方法
    kGetter = 1,
    // 属性写方法
    kSetter = 2,
    // 定义事件
    kEventDeclare = 3,
  };

  /// 嵌入式代码类型
  enum CodeKind {
    // 单行代码
    kLine = 0,
    // 多行代码
    kLong = 1
  };

  /// 嵌入式代码引用类型
  enum CodeRefKind {
    // #this
    kRefThis = 0,
    // 引用变量
    kRefMember = 1,
    // 引用类名
    kRefClass = 2,
    // 引用类成员
    kRefClassMember = 3,
    // 引用原生类名
    kRefNativeClass = 4,
    // 引用编译器特殊字段
    kRefCompiler = 5,
  };

  /// 注释
  struct Comment {
    Origin origin;
    /// 注释原始内容（包含注释符）
    WString raw_content;
    /// 注释内容（不包含注释符）
    WString content;
  };

  /// 修饰符类
  class Modifiers {
  public:
    DECL_MODIFIER(kStatic, 1)
    DECL_MODIFIER(kPublic, 1 << 1)

    Modifiers(int modifier);

    /// 添加一个修饰符
    /// \param modifier 修饰符
    void add(int modifier);

    /// 添加一个修饰符
    /// \param modifier 修饰符
    void operator<<(int modifier);

    /// 移除一个修饰符
    /// \param modifier 修饰符
    void remove(int modifier);

    /// 判断是否包含某个修饰符
    /// \param modifier 修饰符
    bool has(int modifier) const;

  private:
    int modifier_;
  };

  template<typename Param, typename Result>
  class TreeVisitor;

  /// 语法树节点基类
  class Tree {
  public:
    /// 源代码文件位置
    Origin origin_;

    /// 语法树类型
    virtual TreeKind getKind() = 0;
  };

  /// 表达式基类
  class ExpressionTree : public Tree {
  public:
    TreeKind getKind() override;
  };

  /// 完整语句基类
  class StatementTree : public Tree {
  public:
    TreeKind getKind() override;
  };

  /// 标识符
  class IdentifierTree : public ExpressionTree {
  public:
    PTR<Name> name_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(IdentifierTree)
  };

  /// 注解
  class AnnotationTree : public Tree {
  public:
    /// 注解名称
    PTR<IdentifierTree> ident_;
    /// 注解后缀
    PTR<IdentifierTree> suffix_;
    /// 注解的参数
    PTR<ExpressionTree> arg_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(AnnotationTree)
  };

  /// 可以被注解的成员基类
  class AnnotatedTree : public StatementTree {
  public:
    /// 修饰符
    PTR<Modifiers> modifiers_;
    /// 成员名称
    PTR<IdentifierTree> ident_;
    /// 所有注解
    List<PTR<AnnotationTree>> annotations_;
    /// 注释
    PTR<Comment> comment_;

    /// 判断当前成员是否有某个注解
    /// \param name 注解名称
    /// \return 存在该注解则返回true
    bool hasAnnotation(PTR<Name>& name);
  };

  /// 代码块
  class BlockTree : public Tree {
  public:
    /// 包含的语句
    List<PTR<StatementTree>> statements_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(BlockTree)
  };

  /// 变量
  class VariableTree : public AnnotatedTree {
  public:
    /// 变量类型
    PTR<ExpressionTree> type_;
    /// 变量初始值
    PTR<ExpressionTree> initializer_;
    /// 是否为参数
    bool is_parameter_{false};

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(VariableTree)
  };

  /// 方法
  class MethodTree : public AnnotatedTree {
  public:
    /// 方法类型
    MethodKind method_kind_;
    /// 形式参数
    List<PTR<VariableTree>> parameters_;
    /// 返回类型
    PTR<ExpressionTree> return_type_;
    /// 方法体
    PTR<BlockTree> body_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(MethodTree)
  };

  /// 事件
  class EventTree : public MethodTree {
  public:
    /// 事件对象
    PTR<ExpressionTree> event_obj_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(EventTree)
  };

  /// 嵌入式代码
  class CodeTree : public Tree {
  public:
    /// 单行代码还是多行代码
    CodeKind code_kind_;
    /// 包含的语法树
    List<PTR<Tree>> trees_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(CodeTree)
  };

  /// 类
  class ClassTree : public AnnotatedTree {
  public:
    // 父类
    PTR<Tree> extend_clause_;
    // 模板类型
    List<PTR<IdentifierTree>> templates_;
    // 类成员
    List<PTR<AnnotatedTree>> members_;
    // 嵌入式代码
    List<PTR<CodeTree>> codes_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ClassTree)
  };

  /// 编译单元(一个源代码文件)
  class CompilationUnitTree : public AnnotatedTree {
  public:
    /// 包名
    PTR<ExpressionTree> pkg_;
    /// 所有类
    List<PTR<ClassTree>> class_defs_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(CompilationUnitTree)
  };

  /// 如果语句
  class IfTree : public StatementTree {
  public:
    // 条件
    PTR<ExpressionTree> condition_;
    // 条件成立部分的语句
    PTR<BlockTree> then_part_;
    // 否则
    PTR<StatementTree> else_part_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(IfTree)
  };

  /// 假如-是
  class CaseTree : public StatementTree {
  public:
    /// 条件
    List<PTR<ExpressionTree>> conditions_;
    /// 语句
    PTR<BlockTree> body_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(CaseTree)
  };

  /// 假如-是 语句
  class SwitchTree : public StatementTree {
  public:
    // 条件
    PTR<ExpressionTree> selector_;
    // case
    List<PTR<CaseTree>> cases_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(SwitchTree)
  };

  /// 起始值到终止值的循环语句
  class ForLoopTree : public StatementTree {
  public:
    // 赋值表达式
    PTR<ExpressionTree> target_;
    // 起始值
    PTR<ExpressionTree> start_;
    // 终止值
    PTR<ExpressionTree> end_;
    // 步进值
    PTR<ExpressionTree> step_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ForLoopTree)
  };

  /// 遍历循环
  class ForEachTree : public StatementTree {
  public:
    // 遍历源
    PTR<ExpressionTree> source_;
    // 赋值变量1
    PTR<ExpressionTree> var1_;
    // 赋值变量2
    PTR<ExpressionTree> var2_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ForEachTree)
  };

  /// 条件循环
  class WhileLoopTree : public StatementTree {
  public:
    // 条件
    PTR<ExpressionTree> condition_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(WhileLoopTree)
  };

  /// 常量
  template<typename ValueType, TreeKind kind>
  class LiteralTree : public Tree {
  public:
    /// 值
    ValueType value_;

    TreeKind getKind() override {
      return kind;
    }
  };
  /// 字符串常量
  class LiteralStringTree : public LiteralTree<String, TreeKind::kLiteralString> {
  public:
    DECL_ACCEPT_VISITOR(LiteralStringTree)
  };
  /// 字符常量
  class LiteralCharTree : public LiteralTree<char, TreeKind::kLiteralChar> {
  public:
    DECL_ACCEPT_VISITOR(LiteralCharTree)
  };
  /// 布尔值常量
  class LiteralBoolTree : public LiteralTree<bool, TreeKind::kLiteralBool> {
  public:
    DECL_ACCEPT_VISITOR(LiteralBoolTree)
  };
  /// 整数常量
  class LiteralIntTree : public LiteralTree<Int32, TreeKind::kLiteralInt> {
  public:
    DECL_ACCEPT_VISITOR(LiteralIntTree)
  };
  /// 长整数常量
  class LiteralLongTree : public LiteralTree<Int64, TreeKind::kLiteralLong> {
  public:
    DECL_ACCEPT_VISITOR(LiteralLongTree)
  };
  /// 浮点数常量
  class LiteralFloatTree : public LiteralTree<float, TreeKind::kLiteralFloat> {
  public:
    DECL_ACCEPT_VISITOR(LiteralFloatTree)
  };
  /// 小数常量
  class LiteralDoubleTree : public LiteralTree<double, TreeKind::kLiteralDouble> {
  public:
    DECL_ACCEPT_VISITOR(LiteralDoubleTree)
  };

  /// 数组类型表达式
  class ArrayTypeTree : public ExpressionTree {
  public:
    // 类型
    PTR<ExpressionTree> expr_;
    // 数组容量
    PTR<ExpressionTree> size_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ArrayTypeTree)
  };

  /// 泛型类型表达式
  class TemplateTypeTree : public ExpressionTree {
  public:
    // 类型
    PTR<ExpressionTree> expr_;
    // 泛型参数类型
    List<PTR<ExpressionTree>> args_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(TemplateTypeTree)
  };

  /// 字段访问表达式
  class FieldAccessTree : public ExpressionTree {
  public:
    // 前缀
    PTR<ExpressionTree> prefix_;
    // 字段名称
    PTR<IdentifierTree> ident_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(FieldAccessTree)
  };

  /// 调用方法表达式
  class MethodInvokeTree : public ExpressionTree {
  public:
    // 方法名表达式
    PTR<ExpressionTree> expr_;
    // 传入参数
    List<PTR<ExpressionTree>> args_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(MethodInvokeTree)
  };

  /// 创建对象表达式
  class NewClassTree : public ExpressionTree {
  public:
    // 对象类型
    PTR<ExpressionTree> class_name_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(NewClassTree)
  };

  /// 创建数组表达式
  class NewArrayTree : public ExpressionTree {
  public:
    // 数组元素
    List<PTR<ExpressionTree>> elements_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(NewArrayTree)
  };

  /// 数组访问表达式
  class ArrayAccessTree : public ExpressionTree {
  public:
    // 数组对象
    PTR<ExpressionTree> selected_;
    // 索引
    PTR<ExpressionTree> index_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ArrayAccessTree)
  };

  /// 退出循环 表达式
  class BreakTree : public ExpressionTree {
  public:
    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(BreakTree)
  };

  /// 跳过循环 表达式
  class ContinueTree : public ExpressionTree {
  public:
    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ContinueTree)
  };

  /// 返回值 表达式
  class ReturnTree : public ExpressionTree {
  public:
    // 返回值
    PTR<ExpressionTree> value_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ReturnTree)
  };

  /// 订阅事件 表达式
  class SubscribeEventTree : public ExpressionTree {
  public:
    // 要订阅事件的变量
    List<PTR<IdentifierTree>> vars_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(SubscribeEventTree)
  };

  /// 强转类型 表达式
  class TypeCastTree : public ExpressionTree {
  public:
    // 要强转的对象
    PTR<IdentifierTree> expr_;
    // 目标类型
    PTR<IdentifierTree> type_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(TypeCastTree)
  };

  /// 赋值表达式
  class AssignTree : public ExpressionTree {
  public:
    // 要赋值的变量
    PTR<IdentifierTree> var_;
    // 赋值
    PTR<IdentifierTree> value_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(AssignTree)
  };

  /// 交换值表达式
  class ExchangeTree : public ExpressionTree {
  public:
    // 左值
    PTR<IdentifierTree> left_;
    // 右值
    PTR<IdentifierTree> right_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ExchangeTree)
  };

  /// 属于 表达式
  class InstanceOfTree : public ExpressionTree {
  public:
    // 对象
    PTR<IdentifierTree> expr_;
    // 类型
    PTR<IdentifierTree> type_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(InstanceOfTree)
  };

  /// 多元表达式
  class MultiExprTree : public ExpressionTree {
  public:
    // 所有表达式
    List<PTR<IdentifierTree>> expressions_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(MultiExprTree)
  };

  /// 异步等待表达式
  class AwaitTree : public ExpressionTree {
  public:
    // 等待的对象
    PTR<IdentifierTree> expr_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(AwaitTree)
  };

  /// 括号表达式
  class ParensTree : public ExpressionTree {
  public:
    // 括号里的表达式
    PTR<IdentifierTree> expr_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(ParensTree)
  };

  /// 一元表达式
  class UnaryTree : public ExpressionTree {
  public:
    // 表达式
    PTR<IdentifierTree> expr_;
    // 操作符token
    TiecodeToken op_token_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(UnaryTree)
  };

  /// 二元表达式
  class BinaryTree : public ExpressionTree {
  public:
    // 左节点
    PTR<IdentifierTree> left_;
    // 右节点
    PTR<IdentifierTree> right_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(BinaryTree)
  };

  /// 嵌入式代码代码文本
  class CodeTextTree : public ExpressionTree {
  public:
    // 文本内容
    WString content_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(CodeTextTree)
  };

  /// 嵌入式代码引用表达式
  class CodeRefTree : public ExpressionTree {
  public:
    // 引用对象
    PTR<IdentifierTree> expression_;
    // 引用分类
    CodeRefKind ref_kind_;

    TreeKind getKind() override;
    DECL_ACCEPT_VISITOR(CodeRefTree)
  };


  template<typename Param, typename Result>
  class TreeVisitor {
  public:
    DECL_VISIT_TREE(IdentifierTree)
    DECL_VISIT_TREE(AnnotationTree)
    DECL_VISIT_TREE(BlockTree)
    DECL_VISIT_TREE(VariableTree)
    DECL_VISIT_TREE(MethodTree)
    DECL_VISIT_TREE(EventTree)
    DECL_VISIT_TREE(CodeTree)
    DECL_VISIT_TREE(ClassTree)
    DECL_VISIT_TREE(CompilationUnitTree)
    DECL_VISIT_TREE(IfTree)
    DECL_VISIT_TREE(CaseTree)
    DECL_VISIT_TREE(SwitchTree)
    DECL_VISIT_TREE(ForLoopTree)
    DECL_VISIT_TREE(ForEachTree)
    DECL_VISIT_TREE(WhileLoopTree)
    DECL_VISIT_TREE(LiteralStringTree)
    DECL_VISIT_TREE(LiteralCharTree)
    DECL_VISIT_TREE(LiteralBoolTree)
    DECL_VISIT_TREE(LiteralIntTree)
    DECL_VISIT_TREE(LiteralLongTree)
    DECL_VISIT_TREE(LiteralFloatTree)
    DECL_VISIT_TREE(LiteralDoubleTree)
    DECL_VISIT_TREE(ArrayTypeTree)
    DECL_VISIT_TREE(TemplateTypeTree)
    DECL_VISIT_TREE(FieldAccessTree)
    DECL_VISIT_TREE(MethodInvokeTree)
    DECL_VISIT_TREE(NewClassTree)
    DECL_VISIT_TREE(NewArrayTree)
    DECL_VISIT_TREE(ArrayAccessTree)
    DECL_VISIT_TREE(BreakTree)
    DECL_VISIT_TREE(ContinueTree)
    DECL_VISIT_TREE(ReturnTree)
    DECL_VISIT_TREE(SubscribeEventTree)
    DECL_VISIT_TREE(TypeCastTree)
    DECL_VISIT_TREE(AssignTree)
    DECL_VISIT_TREE(ExchangeTree)
    DECL_VISIT_TREE(InstanceOfTree)
    DECL_VISIT_TREE(MultiExprTree)
    DECL_VISIT_TREE(AwaitTree)
    DECL_VISIT_TREE(ParensTree)
    DECL_VISIT_TREE(UnaryTree)
    DECL_VISIT_TREE(BinaryTree)
    DECL_VISIT_TREE(CodeTextTree)
    DECL_VISIT_TREE(CodeRefTree)
  };
}

#endif //TIEC_TREE_H
